/*
 *The code is written by NaLi, All rights reserved.
 */
package com.nali.dal.mongo.util;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author gavin 
 * Created on 2010-7-13
 */
public class DalCollectionUtils {
	
	private DalCollectionUtils() {}
	
	public static final <T> List<T> mergeSortedList(List<T> listOne, List<T> listTwo, Comparator<T> comparator) {
		int listOneSize = listOne.size();
		int listTwoSize = listTwo.size();
		List<T> rtnList = new ArrayList<T> (listOneSize + listTwoSize);
		int i = 0;
		int j = 0;
		while(i < listOneSize && j < listTwoSize) {
			T a = listOne.get(i);
			T b = listTwo.get(j);
			int comparedResult = comparator.compare(a, b);
			if(comparedResult <= 0) {
				rtnList.add(a);
				i++;
			}else{
				rtnList.add(b);
				j++;
			}
		}
		
		while(i < listOneSize) {
			rtnList.add(listOne.get(i++));
		}
		
		while(j < listTwoSize) {
			rtnList.add(listTwo.get(j++));
		}
		
		return rtnList;
	}
	
	public static boolean isEmpty(Collection<?> collection) {
		return collection == null ? true : collection.isEmpty();
	}
	
	public static int getMapSize(int collectionSize, float factor) {
		return (int)Math.ceil(collectionSize / factor);
	}
	
	public static int getMapSize(int collectionSize) {
		return getMapSize(collectionSize, 0.75f);
	}
	
	public static <K,V> HashMap<K, V> newHashMap(int collectionSize) {
		return new HashMap<K, V>(getMapSize(collectionSize));
	}
	
	public static <V> HashSet<V> newHashSet(int collectionSize) {
		return new HashSet<V>(getMapSize(collectionSize));
	}
	
	
	public static <K,V> HashMap<K, V> newLinkedHashMap(int collectionSize) {
		return new LinkedHashMap<K, V>(getMapSize(collectionSize));
	}
	
	public static <E> Set<E> newConcurrentHashSet() {
		return Collections.newSetFromMap(new ConcurrentHashMap<E, Boolean>());
	}
	
	public static <E> Set<E> newConcurrentHashSet(int initialCapacity, float loadFactor, int concurrencyLevel) {
		return Collections.newSetFromMap(new ConcurrentHashMap<E, Boolean>(initialCapacity, loadFactor, concurrencyLevel));
	}
}

